package ws.server.limc.opos
import vaadin.scala._
import vaadin.scala.server._
import com.vaadin.{ ui => vu }
import scala.reflect.ClassTag 
  trait FixContainer extends Container {
    object ContainerProperty {
      def +[T: ClassTag](propertyId: Any, defaultValue: Option[Any] = None): B =
        addContainerProperty(propertyId,  scala.reflect.classTag[T].runtimeClass, defaultValue)
        
        def addComponents(propertyIds:A*)=
          propertyIds.foreach{p=> this +[Component](p) }
      
    }

    override def addContainerProperty(propertyId: Any, propertyType: Class[_], defaultValue: Option[Any] = None) = {
      if (classOf[Component].isAssignableFrom(propertyType))
        super.addContainerProperty(propertyId, classOf[vu.Component], defaultValue)
      else super.addContainerProperty(propertyId, propertyType, defaultValue)
    }
    
    

  }
object ScaladinFix {

trait TableOpable extends Table{

}

  class Table extends  vaadin.scala.Table with FixContainer with AbsSelect{
    
 def rebuildCurCols = {
   val backupCols=this.visibleColumns
    allCol.foreach { _.disableGenerator }
    allCol.foreach { _.enableGenerator }
    visibleColumns=backupCols
  }
    
      def addItem(itemId: A, cells: A*) =
      p.addItem(cells.map { c =>
        (if (c.isInstanceOf[Component]) c.asInstanceOf[Component].p else c).asInstanceOf[Object]
      }.toArray, itemId)
      
      trait ICol{
      def id:A
     def enableGenerator
     def disableGenerator=columnGenerators -= id
     
     allCol.+=(this)
    }
      val allCol=scala.collection.mutable.Buffer[ICol]()

    class Col[Type:ClassTag](val id:A,generator:(O[Type]=>O[A])=null) extends ICol{
    
      ContainerProperty +[Type](id)
      def enableGenerator=
     if(generator!=null)
       columnGenerators.update(id, {e=>
         generator(e.table.getItemOption(e.itemId).flatMap { x => x.getPropertyOption(e.propertyId).flatMap { x => x.value.asInstanceOf[O[Type]] } })
       })
       
   
    }
      class ColV2[Type:ClassTag](val id:A,generator:(Table.ColumnGenerationEvent =>O[A])=null) extends ICol{
    
      ContainerProperty +[Type](id)
      def enableGenerator=
     if(generator!=null)
       columnGenerators.update(id, generator)
       
   
    }
      
      
     class RowItem(val id:A){
       val old=getItemOption(id).getOrElse(wrapItem(p.addItem(id)))
       def apply[T](col:Col[T])(value:T)=old.getProperty(col.id).value_=(value)
     }
      def newItemProxy(id:A)=new RowItem(id)
  }
  trait AbsSelect extends AbstractSelect{
    
    def selectItemIds=itemIds.filter { x => isSelected(x) }
    
     def values:O[Itb[_]]=super.value.collect{case coll:java.util.Collection[_]=>
     scala.collection.convert.WrapAsScala.iterableAsScalaIterable(coll)
     case other=>other ::Nil
    }
        import scala.collection.convert.WrapAsJava._
     def values_=(items:Itb[A])=super.value=asJavaCollection(items)
     
     def addValue(v:A)={
       values = v:: values.getOrElse(Nil).toList
     }
     
     def newItemWithCap(item:A,cap:S)={
      val aitem= getItemOption(item).getOrElse(addItem(item).get)
    setItemCaption(item, cap)
     }
     def valueWithCap_=(items:Itb[(A,S)] )={
       items.foreach{case (item,cap)=>
         newItemWithCap(item,cap)
       }
       values = (items.map{_._1})
     }
     
     def addValueWithCap(item:A,cap:S)={
       newItemWithCap(item,cap)
       addValue(item)
     }
     def addItems(items: Itb[A]) = {
    if (items.nonEmpty) {
      items.foreach { x => addItem(x) }
    }
    this
  }
     def addItemsAndSelectHead(items: Itb[A]) = {
    if (items.nonEmpty) {
      items.foreach { x => addItem(x) }
      value = itemIds.head
    }
    this
  }

  def reAddItemsAndSelectHead(items: Itb[A]) = {
    removeAllItems()
    addItemsAndSelectHead(items)
  }
  }
  
  
  class TwinColSelect extends vaadin.scala.TwinColSelect with AbsSelect {

   
     
  }
}